home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / xinu.arc / XINU1.C < prev    next >
Text File  |  1986-01-03  |  24KB  |  905 lines

  1. /* dscntl.c - dscntl  p. 300 */
  2.  
  3. # include    <conf.h>
  4. # include    <kernel.h>
  5. # include    <proc.h>
  6. # include    <disk.h>
  7.  
  8. /*-----------------------------------------------------------------------------
  9.  *  dscntl  --  control disk driver / device
  10.  *-----------------------------------------------------------------------------
  11.  */
  12. dscntl(devptr, func)
  13.     struct devsw    *devptr;
  14. {
  15.     int    stat;
  16.     char    ps;
  17.  
  18.     disable(ps);
  19.     switch(func)  {
  20.     
  21.         case DSKSYNC:
  22.             stat = dsksync(devptr);
  23.             break;
  24.  
  25.         default:
  26.             stat = SYSERR;
  27.             break;
  28.     }
  29.     restore(ps);
  30.     return(stat);
  31. }
  32. /* dskstrt.c - dskstrt  p. 290 */
  33.  
  34. # include    <conf.h>
  35. # include    <kernel.h>
  36. # include    <disk.h>
  37.  
  38. /*-----------------------------------------------------------------------------
  39.  *  dskstrt  --  start an I/O operation on a disk device
  40.  *-----------------------------------------------------------------------------
  41.  */
  42. dskstrt(dsptr)
  43.     struct dsblk    *dsptr;
  44. {
  45.     struct xbdcb    *xptr;
  46.     struct dtc    *dtptr;
  47.     struct dreq    *drptr;
  48.  
  49.     /* build command for controller */
  50.  
  51.     drptr = dsptr->dreqlst;
  52.     xptr = &dsptr->ddcb;
  53.     xptr->xop    = (char) drptr->drop;        /* opcode            */
  54.     xptr->xunit  = (char) 0;            /* top address bits  */
  55.     xptr->xmaddr = (char) ((drptr->drdba>>8)&0377);    /* middle addr bits  */
  56.     xptr->xladdr = (char) (drptr->drdba & 0377);    /* low address bits  */
  57.     xptr->xcount = (char) 1;            /* number of blocks  */
  58.     xptr->xcntl  = (char) XRETRY;            /* retry code        */
  59.  
  60.     /* feed command to controller through interface */
  61.  
  62.     dtptr = dsptr->dcsr;
  63.     dtptr->dt_dar  = drptr->drbuff;
  64.     dtptr->dt_car  = xptr;
  65.     dtptr->dt_xdar = dtptr->dt_xcar = 0;
  66.     dtptr->dt_csr  = DTINTR | DTGO;
  67. }
  68. /* dsseek.c - dsseek  p. 297 */
  69.  
  70. # include    <conf.h>
  71. # include    <kernel.h>
  72. # include    <proc.h>
  73. # include    <disk.h>
  74.  
  75. /*-----------------------------------------------------------------------------
  76.  *  dsseek  --  schedule a request to move the disk arm
  77.  *-----------------------------------------------------------------------------
  78.  */
  79. dsseek(devptr, block)
  80.     struct devsw    *devptr;
  81.     DBADDR    block;
  82. {
  83.     struct dreq    *drptr;
  84.     char    ps;
  85.  
  86.     disable(ps);
  87.     drptr = (struct dreq *) getbuf(dskrbp);
  88.     drptr->drdba  = block;
  89.     drptr->drpid  = currpid;
  90.     drptr->drbuff = NULL;
  91.     drptr->drop   = DSEEK;
  92.  
  93.     /* enqueued with normal policy like other read/write requests */
  94.  
  95.     dskenq(drptr,devptr->dvioblk);
  96.     restore(ps);
  97.     return(OK);
  98. }
  99. /* dsinit.c - dsinit  p. 291 */
  100.  
  101. # include    <conf.h>
  102. # include    <kernel.h>
  103. # include    <disk.h>
  104.  
  105. # ifdef    Ndsk
  106. struct dsblk    dstab[Ndsk];
  107. # endif
  108. int    dskdbp, dskrbp;
  109.  
  110. /*-----------------------------------------------------------------------------
  111.  *  dsinit  --  initialize disk drive device
  112.  *-----------------------------------------------------------------------------
  113.  */
  114. dsinit(devptr)
  115.     struct devsw    *devptr;
  116. {
  117.     struct dsblk    *dsptr;
  118.     struct dtc    *dtptr;
  119.     int    status;
  120.     char    ps;
  121.  
  122.     disable(ps);
  123.     devptr->dvioblk = dsptr = &dstab[devptr->dvminor];
  124.     dsptr->dcsr    = devptr->dvcsr;
  125.     dsptr->dreqlst = DRNULL;
  126.     dsptr->dnum    = devptr->dvnum;
  127.     dsptr->dibsem  = screate(1);
  128.     dsptr->dflsem  = screate(1);
  129.     dsptr->ddirsem = screate(1);
  130.     dsptr->dnfiles = 0;
  131.     dsptr->ddir    = getbuf(dskdbp);
  132.     iosetvec(devptr->dvnum, dsptr, dsptr);
  133.  
  134.     /* read directory block; setup read command then start interface */
  135.  
  136.     dsptr->ddcb.xop    = (char) XOREAD;
  137.     dsptr->ddcb.xunit  = (char) 0;
  138.     dsptr->ddcb.xcntl  = (char) XRETRY;
  139.     dsptr->ddcb.xmaddr = (char) ((DIRBLK>>8)&(0377));
  140.     dsptr->ddcb.xladdr = (char) (DIRBLK & 0377);
  141.     dsptr->ddcb.xcount = (char) 1;
  142.     dtptr = dsptr->dcsr;
  143.     dtptr->dt_dar  = dsptr->ddir;
  144.     dtptr->dt_car  = &dsptr->ddcb;
  145.     dtptr->dt_xdar = dtptr->dt_xcar = NULL;
  146.     dtptr->dt_csr  = DTGO;
  147.     while (((status=dtptr->dt_csr) & DTDONE) == 0)
  148.         ;
  149.     if (status & DTERROR)
  150.         panic("disk error");
  151.     restore(ps);
  152.     return(OK);
  153. }
  154. /* dsksync.c - dsksync  p. 300 */
  155.  
  156. # include    <conf.h>
  157. # include    <kernel.h>
  158. # include    <proc.h>
  159. # include    <disk.h>
  160.  
  161. /*-----------------------------------------------------------------------------
  162.  *  dsksync  --  wait for all outstanding disk requests before returning
  163.  *-----------------------------------------------------------------------------
  164.  */
  165. dsksync(devptr)
  166.     struct devsw    *devptr;
  167. {
  168.     struct dreq    *drptr, *p, *q;
  169.     int    stat;
  170.     
  171.     if ((q=(devptr->dvioblk)->dreqlst) == DRNULL)
  172.         return(OK);
  173.     drptr = (struct dreq *) getbuf(dskrbp);
  174.     drptr->drdba  = 0;
  175.     drptr->drpid  = currpid;
  176.     drptr->drbuff = NULL;
  177.     drptr->drop   = DSYNC;
  178.     drptr->drnext = DRNULL;
  179.  
  180.     /* place at end of request list */
  181.  
  182.     for (p=q->drnext ; p!=DRNULL ; q=p,p=p->drnext)
  183.         ;
  184.     q->drnext = drptr;
  185.     drptr->drstat = SYSERR;
  186.     suspend(currpid);
  187.     stat = drptr->drstat;
  188.     freebuf(drptr);
  189.     return(stat);
  190. }
  191. /* dswrite.c - dswrite  p. 296 */
  192.  
  193. # include    <conf.h>
  194. # include    <kernel.h>
  195. # include    <proc.h>
  196. # include    <disk.h>
  197.  
  198. /*-----------------------------------------------------------------------------
  199.  *  dswrite  --  write a block ( system buffer ) onto a disk device
  200.  *-----------------------------------------------------------------------------
  201.  */
  202. dswrite(devptr, buff, block)
  203.     struct devsw    *devptr;
  204.     char    *buff;
  205.     DBADDR    block;
  206. {
  207.     struct dreq    *drptr;
  208.     char    ps;
  209.  
  210.     disable(ps);
  211.     drptr = (struct dreq *) getbuf(dskrbp);
  212.     drptr->drbuff = buff;
  213.     drptr->drdba  = block;
  214.     drptr->drpid  = currpid;
  215.     drptr->drop   = DWRITE;
  216.     dskenq(drptr,devptr->dvioblk);
  217.     restore(ps);
  218.     return(OK);
  219. }
  220. /* chprio.c - chprio  p. 76 */
  221.  
  222. #include    <conf.h>
  223. #include    <kernel.h>
  224. #include    <proc.h>
  225.  
  226. /*-----------------------------------------------------------------------------
  227.  * chprio  --  change the scheduling priority of a process
  228.  *-----------------------------------------------------------------------------
  229.  */
  230.  
  231. SYSCALL    chprio(pid,newprio)
  232.     int    pid;
  233.     int    newprio;        /* newprio > 0                       */
  234. {
  235.     int    oldprio;
  236.     struct pentry    *pptr;
  237.     char    ps;
  238.  
  239.     disable(ps);
  240.     if (isbadpid(pid) || newprio<=0 ||
  241.         (pptr = &proctab[pid])->pstate == PRFREE)  {
  242.         restore(ps);
  243.         return(SYSERR);
  244.     }
  245.  
  246.     oldprio = pptr->pprio;
  247.     pptr->pprio = newprio;
  248.     switch( pptr->pstate)  {
  249.       case PRCURR : /*
  250.              * The process is already running. so just change
  251.              * the priority. We reschedule the system if the
  252.              * new priority is less than the old priority.
  253.              * We don't have to reschedule if the priority is
  254.              * greater : we are already the greatest priority
  255.              * process running. But, if the priority is less
  256.              * we just might be smaller than some other process
  257.              */
  258.             if( oldprio > newprio ) resched();
  259.             break;
  260.       case PRREADY: /*
  261.              * In this case the process is on the ready queue.
  262.              * We first need to take it off the ready queue. We
  263.              * than change the priority, and place it back. The
  264.              * last step is to run resched, just in case. The
  265.              * real check should be to see if newprio is bigger
  266.              * than the priority of the current running process.
  267.              * If it is, we should can resched. The reason we
  268.              * don't do it is because if resched every changes
  269.              * we would have to go back and 'fix' everything.
  270.              */
  271.             dequeue(pid);
  272.             insert(pid,rdyhead,newprio);
  273.             resched();
  274.             break;
  275.       case PRRECV :
  276.       case PRSLEEP:
  277.       case PRSUSP :
  278.       case PRWAIT : /*
  279.              * In these cases the process is not on the ready
  280.              * queue. So we only need to change the priority
  281.              * and exit.
  282.              */
  283.             break;
  284.       default     : /* if we get here, the system is corrupted */
  285.             restore(ps);
  286.             return(SYSERR);
  287.     }
  288.     restore(ps);
  289.     return(oldprio);
  290. }
  291. /* create.c - create, newpid  p. 74 */
  292.  
  293. # include    <conf.h>
  294. # include    <kernel.h>
  295. # include    <proc.h>
  296. # include    <mem.h>
  297.  
  298. /*-----------------------------------------------------------------------------
  299.  * create  --  create a process to start running a procedure
  300.  *-----------------------------------------------------------------------------
  301.  */
  302. SYSCALL    create(procaddr,ssize,priority,name,nargs,args)
  303.     int    *procaddr;        /* procedure address                 */
  304.     int    ssize;            /* stack size in words               */
  305.     int    priority;        /* process priority >= 0             */
  306.     char    *name;            /* name ( for debugging )            */
  307.     int    nargs;            /* number of args that follow        */
  308.     int    args;            /* arguments (treated like an array) */
  309. {
  310.     int    pid;            /* stores new process id             */
  311.     struct pentry    *pptr;        /* pointer to process table entry    */
  312.     int    i;
  313.     int    *a;            /* points to list of arguments       */
  314.     int    *saddr;            /* stack address                     */
  315.     char    ps;            /* saved processor status            */
  316.     int    INITRET();
  317.  
  318.     disable(ps);
  319.     ssize = roundew(ssize);
  320.     if ( ssize < MINSTK || ((saddr=getstk(ssize)) == SYSERR ) ||
  321.         (pid=newpid()) == SYSERR || isodd(procaddr) ||
  322.         priority < 1 )  {
  323.         restore(ps);
  324.         return(SYSERR);
  325.     }
  326.     numproc++;
  327.     pptr = &proctab[pid];
  328.     pptr->pstate = PRSUSP;
  329.     for (i=0; i<PNMLEN && (pptr->pname[i]=name[i])!=0; i++)
  330.         ;
  331.     pptr->pprio = priority;
  332.     pptr->pbase = (short)saddr;
  333.     pptr->pstklen = ssize;
  334.     pptr->plimit = (short) ( saddr - ssize + 1);
  335.     pptr->pargs = nargs;
  336.     for (i=0; i<PNREGS; i++)
  337.         pptr->pregs[i] = INITREG;
  338.     pptr->pregs[PC] = pptr->paddr = (short)procaddr;
  339.     pptr->pregs[PS] = INITPS;
  340.     a = (&args) + (nargs-1);    /* point to last argument            */
  341.     for ( ; nargs>0; nargs--)    /* machine dependent, copy args      */
  342.         *saddr-- = *a--;    /*  onto created process' stack      */
  343.     *saddr = (int)INITRET;        /* push on return address            */
  344.     pptr->pregs[SP] = (int)saddr;
  345.     restore(ps);
  346.     return(pid);
  347. }
  348.  
  349. /*-----------------------------------------------------------------------------
  350.  * newpid  --  obtain a new ( free ) process id
  351.  *-----------------------------------------------------------------------------
  352.  */
  353. LOCAL    newpid()
  354. {
  355.     int    pid;            /* process id to return              */
  356.     int    i;
  357.  
  358.     for (i=0; i<NPROC; i++)  {    /* check all NPROC slots             */
  359.         if ((pid=nextproc--) <= 0)
  360.             nextproc = NPROC-1;
  361.         if (proctab[pid].pstate == PRFREE)
  362.             return(pid);
  363.     }
  364.     return(SYSERR);
  365. }
  366. /* getbuf.c - getbuf  p. 236 */
  367.  
  368. #include    <conf.h>
  369. #include    <kernel.h>
  370. #include    <mark.h>
  371. #include    <bufpool.h>
  372.  
  373. /*-----------------------------------------------------------------------------
  374.  *  getbuf  --  get a buffer from a preestablished buffer pool
  375.  *-----------------------------------------------------------------------------
  376.  */
  377.  
  378. int    *
  379. getbuf(poolid)
  380. int    poolid;
  381. {
  382.     char    ps;
  383.     int    *buf;
  384.  
  385. #ifdef    MEMMARK
  386.     if (unmarked(bpmark))
  387.         return((int *)SYSERR);
  388. #endif
  389.     if (poolid<0 || poolid>=nbpools)
  390.         return((int *)SYSERR);
  391.     wait(bptab[poolid].bpsem);
  392.     disable(ps);
  393.     buf = bptab[poolid].bpnext;
  394.     bptab[poolid].bpnext = *buf;
  395.     restore(ps);
  396.     *buf++ = poolid;
  397.     return(buf);
  398. }
  399. /* getpid.c - getpid  p. 77 */
  400.  
  401. # include    <conf.h>
  402. # include    <kernel.h>
  403. # include    <proc.h>
  404.  
  405. /*-----------------------------------------------------------------------------
  406.  * getpid  --  get the process id of currently executing process
  407.  *-----------------------------------------------------------------------------
  408.  */
  409. SYSCALL    getpid()
  410. {
  411.     return(currpid);
  412. }
  413. /* iblfree.c - iblfree  p. 316 */
  414.  
  415. # include    <conf.h>
  416. # include    <kernel.h>
  417. # include    <io.h>
  418. # include    <disk.h>
  419. # include    <file.h>
  420. # include    <dir.h>
  421.  
  422. /*-----------------------------------------------------------------------------
  423.  *  iblfree  --  free a list of iblocks given the number of the first
  424.  *-----------------------------------------------------------------------------
  425.  */
  426. iblfree(diskdev, iblist)
  427.     int    diskdev;
  428.     IBADDR    iblist;
  429. {
  430.     IBADDR    ilast;
  431.     struct iblk    iblock;
  432.     struct dir    *dirptr;
  433.     int    sem;
  434.     DBADDR    dba;
  435.     int    j;
  436.  
  437.     if (iblist == IBNULL)
  438.         return(OK);
  439.     dirptr = dsdirec(diskdev);
  440.     ibget(diskdev, iblist, &iblock);
  441.     for (ilast=iblist ; iblock.ib_next!=IBNULL ; )  {
  442.         for (j=0 ; j<IBLEN ; j++)
  443.             if ((dba=iblock.ib_dba[j]) != DBNULL)
  444.                 lfsdfree(diskdev, dba);
  445.         ilast = iblock.ib_next;
  446.         ibget(diskdev, ilast, &iblock);
  447.     }
  448.     for (j=0 ; j<IBLEN ; j++)
  449.         if ((dba=iblock.ib_dba[j]) != DBNULL)
  450.             lfsdfree(diskdev, dba);
  451.     sem = ((struct dsblk *)devtab[diskdev].dvioblk)->dflsem;
  452.     wait(sem);
  453.     iblock.ib_next = dirptr->d_filst;
  454.     dirptr->d_filst = iblist;
  455.     ibput(diskdev, ilast, &iblock);
  456.     write(diskdev, dskbcpy(dirptr), DIRBLK);
  457.     signal(sem);
  458.     return(OK);
  459. }
  460. /* ioinit.c - ioinit, iosetvec  p. 154 */
  461.  
  462. # include    <conf.h>
  463. # include    <kernel.h>
  464. # include    <io.h>
  465.  
  466. /*-----------------------------------------------------------------------------
  467.  *  ioinit  --  standard interrupt vector and dispatch initialization
  468.  *-----------------------------------------------------------------------------
  469.  */
  470. ioinit(descrp)
  471.     int    descrp;
  472. {
  473.     int    minor;
  474.  
  475.     if (isbaddev(descrp))
  476.         return(SYSERR);
  477.     minor = devtab[descrp].dvminor;
  478.     iosetvec(descrp, minor, minor);
  479.     return(OK);
  480. }
  481.  
  482. /*-----------------------------------------------------------------------------
  483.  *  iosetvec  --  fill in interrupt vectors and dispatch table entries
  484.  *-----------------------------------------------------------------------------
  485.  */
  486. iosetvec(descrp, incode, outcode)
  487.     int    descrp;
  488.     int    incode;
  489.     int    outcode;
  490. {
  491.     struct devsw    *devptr;
  492.     struct intmap    *map;
  493.     struct vector    *vptr;
  494.  
  495.     if (isbaddev(descrp))
  496.         return(SYSERR);
  497.     devptr = &devtab[descrp];
  498.     map = &intmap[devptr->dvnum];    /* fill in tnterrupt dispatch map    */
  499.     map->iin = devptr->dviint;    /*  with addresses of high-level     */
  500.     map->icode = incode;        /*  input and output interrupt       */
  501.     map->iout = devptr->dvoint;    /*  handlers and minor device        */
  502.     map->ocode = outcode;        /*  numbers                          */
  503.     vptr = (struct vector *)devptr->dvivec;
  504.     vptr->vproc = (char *)INTVECI;    /* fill in input interrupt vector PC */
  505.     vptr->vps = descrp | DISABLE;    /*  and PS values                    */
  506.     vptr = (struct vector *)devptr->dvovec;
  507.     vptr->vproc = (char *)INTVECO;    /* fill in output interrupt vector   */
  508.     vptr->vps = descrp | DISABLE;    /*  PC and PS values                 */
  509.     return(OK);
  510. }
  511. /* lfclose.c - lfclose  p. 339 */
  512.  
  513. # include    <conf.h>
  514. # include    <kernel.h>
  515. # include    <proc.h>
  516. # include    <disk.h>
  517. # include    <file.h>
  518.  
  519. /*-----------------------------------------------------------------------------
  520.  *  lfclose  --  close a file by flushing output and freeing device slot
  521.  *-----------------------------------------------------------------------------
  522.  */
  523. lfclose(devptr)
  524.     struct devsw    *devptr;
  525. {
  526.     struct dsblk    *dsptr;
  527.     struct dir    *dirptr;
  528.     struct flblk    *flptr;
  529.     int    diskdev;
  530.     char    ps;
  531.  
  532.     disable(ps);
  533.     flptr = (struct flblk *)devptr->dvioblk;
  534.     if (flptr->fl_pid != currpid)  {
  535.         restore(ps);
  536.         return(SYSERR);
  537.     }
  538.     diskdev = flptr->fl_dev;
  539.     dsptr = (struct dsblk *)devtab[diskdev].dvioblk;
  540.     dirptr = (struct dir *)dsptr->ddir;
  541.     if ((flptr->fl_mode&FLWRITE) && flptr->fl_dch)
  542.         lfsflush(flptr);
  543.     flptr->fl_pid = 0;
  544.     dsptr->dnfiles--;
  545.     write(diskdev, dskbcpy(dirptr), DIRBLK);
  546.     restore(ps);
  547.     return(OK);
  548. }
  549. /* lfread.c - lfread  p. 337 */
  550.  
  551. # include    <conf.h>
  552. # include    <kernel.h>
  553. # include    <disk.h>
  554. # include    <file.h>
  555. # include    <dir.h>
  556.  
  557. /*----------------------------------------------------------------------------
  558.  *  lfread  --  read from a previously  opened  disk file
  559.  *----------------------------------------------------------------------------
  560.  */
  561.  
  562. lfread(devptr, buff, count)
  563. struct    devsw    *devptr;
  564. char    *buff;
  565. int    count;
  566. {
  567.     int    done;
  568.     int    ichar;
  569.  
  570.     if (count < 0)
  571.         return(SYSERR);
  572.     for (done = 0; done < count; done++)
  573.         if ( (ichar = lfgetc(devptr)) == SYSERR)
  574.             return(SYSERR);
  575.         else if (ichar == EOF)  {    /* EOF before finished */
  576.             if (done == 0)
  577.                 return(EOF);
  578.             else
  579.                 return(done);
  580.         } else
  581.             *buff++ = (char)ichar;
  582.     return(done);
  583. }
  584. /* lfsflush.c - lfsflush  p. 330 */
  585.  
  586. # include    <conf.h>
  587. # include    <kernel.h>
  588. # include    <disk.h>
  589. # include    <file.h>
  590. # include    <dir.h>
  591.  
  592. /*-----------------------------------------------------------------------------
  593.  *  lfsflush  --  flush data and i-block for a file
  594.  *-----------------------------------------------------------------------------
  595.  */
  596. lfsflush(flptr)
  597.     struct flblk    *flptr;
  598. {
  599.     DBADDR    dba;
  600.  
  601.     if (!flptr->fl_dch)
  602.         return(SYSERR);
  603.     dba = flptr->fl_iblk.ib_dba[flptr->fl_ipnum];
  604.     write(flptr->fl_dev, dskbcpy(flptr->fl_buff), dba);
  605.     flptr->fl_dch = FALSE;
  606.     return ( OK );
  607. }
  608. /* close.c - close  p. 149 */
  609.  
  610. # include    <conf.h>
  611. # include    <kernel.h>
  612. # include    <io.h>
  613.  
  614. /*-----------------------------------------------------------------------------
  615.  *  close  --  close a device
  616.  *-----------------------------------------------------------------------------
  617.  */
  618. close(descrp)
  619.     int    descrp;
  620. {
  621.     struct devsw    *devptr;
  622.  
  623.     if (isbaddev(descrp))
  624.         return(SYSERR);
  625.     devptr = &devtab[descrp];
  626.     return ((*devptr->dvclose)(devptr));
  627. }
  628. /* dfalloc.c - dfalloc  p. 325 */
  629.  
  630. # include    <conf.h>
  631. # include    <kernel.h>
  632. # include    <disk.h>
  633. # include    <file.h>
  634.  
  635. /*-----------------------------------------------------------------------------
  636.  *  dfalloc  --  allocate a device table entry for a disk file; return id
  637.  *-----------------------------------------------------------------------------
  638.  */
  639. dfalloc()
  640. {
  641.     int    i;
  642.  
  643.     for (i=0 ; i<Ndf ; i++)
  644.         if (fltab[i].fl_pid == 0)  {
  645.             fltab[i].fl_pid = getpid();
  646.             return(i);
  647.         }
  648.     return(SYSERR);
  649. }
  650. /* getc.c - getc  p. 146 */
  651.  
  652. # include    <conf.h>
  653. # include    <kernel.h>
  654. # include    <io.h>
  655.  
  656. /*-----------------------------------------------------------------------------
  657.  *  getc  --  get one character from a device
  658.  *-----------------------------------------------------------------------------
  659.  */
  660. getc(descrp)
  661.     int    descrp;
  662. {
  663.     struct devsw    *devptr;
  664.  
  665.     if (isbaddev(descrp))
  666.         return(SYSERR);
  667.     devptr = &devtab[descrp];
  668.     return ((*devptr->dvgetc)(devptr));
  669. }
  670. /* getstk.c - getstk  p. 108 */
  671.  
  672. # include    <conf.h>
  673. # include    <kernel.h>
  674. # include    <mem.h>
  675.  
  676. /*-----------------------------------------------------------------------------
  677.  *  getstk  --  allocate stack memory, returning address of topmost int
  678.  *-----------------------------------------------------------------------------
  679.  */
  680. int    *getstk(nbytes)
  681.     unsigned int    nbytes;
  682. {
  683.     char    ps;
  684.     struct mblock    *p, *q;        /* q follows p along memlist         */
  685.     struct mblock    *fits, *fitsq;
  686.     int    len;
  687.  
  688.     disable(ps);
  689.     if (nbytes == 0)  {
  690.         restore(ps);
  691.         return((int *)SYSERR);
  692.     }
  693.     nbytes = (unsigned int) roundew(nbytes);
  694.     fits = NULL;
  695.     q = &memlist;
  696.     for (p = q->mnext ; p != NULL ; q = p, p = p->mnext)
  697.         if ( p->mlen >= nbytes )  {
  698.             fitsq = q;
  699.             fits = p;
  700.         }
  701.     if (fits == NULL)  {
  702.         restore(ps);
  703.         return((int *)SYSERR);
  704.     }
  705.     if (nbytes == fits->mlen)  {
  706.         fitsq->mnext = fits->mnext;
  707.         len = nbytes;
  708.     }  else  {
  709.         len = fits->mlen;
  710.         fits->mlen -= nbytes;
  711.     }
  712.     fits = ((int)fits) + len - sizeof(int);
  713.     *((int *)fits) = nbytes;
  714.     restore(ps);
  715.     return((int *)fits);
  716. }
  717. /* ibnew.c - ibnew  p. 314 */
  718.  
  719. # include    <conf.h>
  720. # include    <kernel.h>
  721. # include    <io.h>
  722. # include    <disk.h>
  723. # include    <file.h>
  724. # include    <dir.h>
  725.  
  726. /*-----------------------------------------------------------------------------
  727.  *  ibnew  --  allocate a new iblock from free list on disk
  728.  *-----------------------------------------------------------------------------
  729.  */
  730. ibnew(diskdev, writedir)
  731.     int    diskdev;
  732.     Bool    writedir;
  733. {
  734.     struct dir    *dirptr;
  735.     struct iblk    iblock;
  736.     IBADDR    inum;
  737.     int    i;
  738.     int    sem;
  739.  
  740.     sem = ((struct dsblk *)devtab[diskdev].dvioblk)->dflsem;
  741.     dirptr = dsdirec(diskdev);
  742.     wait(sem);
  743.     inum = dirptr->d_filst;
  744.     ibget(diskdev, inum, &iblock);
  745.     dirptr->d_filst = iblock.ib_next;
  746.     if (writedir)
  747.         write(diskdev, dskbcpy(dirptr), DIRBLK);
  748.     signal(sem);
  749.     ibclear(&iblock, 0L);
  750.     ibput(diskdev, inum, &iblock);
  751.     return(inum);
  752. }
  753. /* insert.c - insert  p. 48 */
  754.  
  755. # include    <conf.h>
  756. # include    <kernel.h>
  757. # include    <q.h>
  758.  
  759. /*-----------------------------------------------------------------------------
  760.  * insert.c  --  insert a process into a q list in key order
  761.  *-----------------------------------------------------------------------------
  762.  */
  763. int    insert(proc, head, key)
  764.     int    proc;            /* process to insert                 */
  765.     int    head;            /* q index of head of list           */
  766.     int    key;            /* key to use for this process       */
  767. {
  768.     int    next;            /* runs through list                 */
  769.     int    prev;
  770.  
  771.     next = q[head].qnext;
  772.     while (q[next].qkey < key)    /* tail has MAXINT as key            */
  773.         next = q[next].qnext;
  774.     q[proc].qnext = next;
  775.     q[proc].qprev = prev = q[next].qprev;
  776.     q[proc].qkey  = key;
  777.     q[prev].qnext = proc;
  778.     q[next].qprev = proc;
  779.     return(OK);
  780. }
  781. /* ionull.c - ionull  p. 151 */
  782.  
  783. # include    <conf.h>
  784. # include    <kernel.h>
  785.  
  786. /*-----------------------------------------------------------------------------
  787.  *  ionull  --  do nothing (used for "don't care" entries in devtab)
  788.  *-----------------------------------------------------------------------------
  789.  */
  790. ionull()
  791. {
  792.     return(OK);
  793. }
  794. /* lfgetc.c - lfgetc  p. 334 */
  795.  
  796. # include    <conf.h>
  797. # include    <kernel.h>
  798. # include    <proc.h>
  799. # include    <disk.h>
  800. # include    <file.h>
  801. # include    <dir.h>
  802.  
  803. /*-----------------------------------------------------------------------------
  804.  *  lfgetc  --  get next character from (buffered) disk file
  805.  *-----------------------------------------------------------------------------
  806.  */
  807. lfgetc(devptr)
  808.     struct devsw    *devptr;
  809. {
  810.     struct flblk    *flptr;
  811.     char    nextch;
  812.     char    ps;
  813.  
  814.     disable(ps);
  815.     flptr = (struct flblk *)devptr->dvioblk;
  816.     if (flptr->fl_pid!=currpid || !(flptr->fl_mode&FLREAD))  {
  817.         restore(ps);
  818.         return(SYSERR);
  819.     }
  820.     if (flptr->fl_pos >= (flptr->fl_dent)->fdlen)  {
  821.         restore(ps);
  822.         return(EOF);
  823.     }
  824.     if (flptr->fl_bptr >= &flptr->fl_buff[DBUFSIZ])  {
  825.         if (flptr->fl_dch)
  826.             lfsflush(flptr);
  827.         lfsetup(flptr->fl_dev, flptr);
  828.     }
  829.     nextch = *(flptr->fl_bptr)++;
  830.     flptr->fl_pos++;
  831.     restore(ps);
  832.     return(nextch);
  833. }
  834. /* lfsdfree.c - lfsdfree  p. 329 */
  835.  
  836. # include    <conf.h>
  837. # include    <kernel.h>
  838. # include    <disk.h>
  839. # include    <file.h>
  840. # include    <dir.h>
  841.  
  842. /*-----------------------------------------------------------------------------
  843.  *  lfsdfree  --  free a data block given its address
  844.  *-----------------------------------------------------------------------------
  845.  */
  846. lfsdfree(diskdev, dba)
  847.     int    diskdev;
  848.     DBADDR    dba;
  849. {
  850.     struct dir    *dirptr;
  851.     int    dirsem;
  852.     struct freeblk    *buf;
  853.  
  854.     dirptr = dsdirec(diskdev);
  855.     dirsem = devtab[diskdev].dvioblk->dflsem;
  856.     buf = (struct freeblk *)getbuf(dskdbp);
  857.     wait(dirsem);
  858.     buf->fbnext = dirptr->d_fblst;
  859.     dirptr->d_fblst = dba;
  860.     write(diskdev, buf, dba);
  861.     write(diskdev, dskbcpy(dirptr), DIRBLK);
  862.     signal(dirsem);
  863.     return(OK);
  864. }
  865. /* lfsnewd.c - lfsnewd  p. 328 */
  866.  
  867. # include    <conf.h>
  868. # include    <kernel.h>
  869. # include    <disk.h>
  870. # include    <file.h>
  871. # include    <dir.h>
  872.  
  873. # define    DFILLER        '+'
  874.  
  875. /*-----------------------------------------------------------------------------
  876.  *  lfsnewd  --  allocate a new data block from free list on disk
  877.  *-----------------------------------------------------------------------------
  878.  */
  879. lfsnewd(diskdev, flptr)
  880.     int    diskdev;
  881.     struct flblk    *flptr;
  882. {
  883.     struct iblock    *ibptr;
  884.     struct dir    *dirptr;
  885.     struct freeblk    *fbptr;
  886.     char    *buf;
  887.     int    sem;
  888.     DBADDR    dba;
  889.     int    i;
  890.  
  891.     dirptr = dsdirec(diskdev);
  892.     fbptr = (struct freeblk *)(buf = flptr->fl_buff);
  893.     sem = ((struct dsblk *)devtab[diskdev].dvioblk)->dflsem;
  894.     wait(sem);
  895.     dba = dirptr->d_fblst;
  896.     read(diskdev, fbptr, dba);
  897.     dirptr->d_fblst = fbptr->fbnext;
  898.     write(diskdev, dskbcpy(dirptr), DIRBLK);
  899.     signal(sem);
  900.     for (i=0 ; i<DBUFSIZ ; i++)
  901.         *buf++ = DFILLER;
  902.     write(diskdev, dskbcpy(fbptr), dba);
  903.     return(dba);
  904. }
  905.